import 'dart:io';
import 'dart:convert';
import 'package:path/path.dart' as path;
import 'package:path_provider/path_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart';

/// AsrFFI 类用于处理语音识别相关的 FFI 调用
/// 该类确保所有依赖文件都从 assets 目录加载，不依赖项目外部文件
class AsrFFI {
  static final AsrFFI _instance = AsrFFI._internal();
  factory AsrFFI() => _instance;
  AsrFFI._internal();

  // 私有变量
  late String _workRoot; // 临时工作根目录
  late String _dllDir; // 提取后的 dlls 目录
  late String _modelDir; // 提取后的模型目录
  bool _initialized = false;
  final List<String> _recognitionHistory = [];

  // 日志相关变量
  static final List<String> _logBuffer = [];
  static String? _logFilePath;
  static bool _enableLogging = true;

  /// 静态初始化方法，供 main.dart 调用
  static Future<void> initialize() async {
    await AsrFFI()._initialize();
  }

  /// 内部初始化方法
  Future<void> _initialize() async {
    if (_initialized) return;

    debugPrint('========== AsrFFI 初始化开始 ==========');
    await _initializeLogging();
    await _setupWorkingDirectories();
    await _validateRequiredFiles();
    _initialized = true;
    debugPrint('========== AsrFFI 初始化完成 ==========');
  }

  /// 设置工作目录
  Future<void> _setupWorkingDirectories() async {
    debugPrint('========== 目录设置开始 ==========');

    // 获取应用程序的可执行文件目录
    String appDir;

    if (Platform.isWindows) {
      // Windows: 使用可执行文件所在目录
      appDir = path.dirname(Platform.resolvedExecutable);
      debugPrint('Windows平台，应用程序目录: $appDir');
    } else if (Platform.isLinux || Platform.isMacOS) {
      // Linux/macOS: 使用可执行文件所在目录
      appDir = path.dirname(Platform.resolvedExecutable);
      debugPrint('${Platform.operatingSystem}平台，应用程序目录: $appDir');
    } else {
      // 其他平台回退到临时目录
      final temp = await getTemporaryDirectory();
      appDir = temp.path;
      debugPrint('未知平台，使用临时目录: $appDir');
    }

    _workRoot = path.join(appDir, 'funasr_runtime');
    _dllDir = path.join(_workRoot, 'dlls');
    _modelDir = path.join(_workRoot, 'models');

    debugPrint('运行时根目录: $_workRoot');
    debugPrint('DLL目录: $_dllDir');
    debugPrint('模型目录: $_modelDir');

    // 创建必要的目录
    await Directory(_dllDir).create(recursive: true);
    await Directory(_modelDir).create(recursive: true);

    debugPrint('✓ 目录创建完成');
    debugPrint('========== 目录设置完成 ==========');
  }

  /// 验证必需的文件是否存在
  Future<void> _validateRequiredFiles() async {
    debugPrint('========== 验证必需文件 ==========');

    // 检查关键可执行文件
    final requiredExecutables = [
      'funasr-onnx-offline.exe',
      'funasr-onnx-online-asr.exe',
    ];

    for (final exe in requiredExecutables) {
      final exePath = path.join(_dllDir, exe);
      if (!File(exePath).existsSync()) {
        debugPrint('❌ 缺少可执行文件: $exePath');
      } else {
        debugPrint('✓ 找到可执行文件: $exe');
      }
    }

    // 检查关键DLL文件
    final requiredDlls = [
      'onnxruntime.dll',
      'avcodec-60.dll',
      'avformat-60.dll',
      'avutil-58.dll',
    ];

    for (final dll in requiredDlls) {
      final dllPath = path.join(_dllDir, dll);
      if (!File(dllPath).existsSync()) {
        debugPrint('⚠️ 缺少DLL文件: $dllPath');
      } else {
        debugPrint('✓ 找到DLL文件: $dll');
      }
    }

    // 检查模型目录
    final modelDirs = [
      'speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx',
      'paraformer-zh-streaming-onnx',
    ];

    bool hasValidModel = false;
    for (final modelDirName in modelDirs) {
      final modelPath = path.join(_modelDir, modelDirName);
      if (Directory(modelPath).existsSync()) {
        final modelFile = _findModelFile(modelPath, [
          'model_quant.onnx',
          'model.onnx',
        ]);
        if (modelFile != null) {
          debugPrint('✓ 找到有效模型: $modelDirName');
          hasValidModel = true;
          break;
        }
      }
    }

    if (!hasValidModel) {
      debugPrint('⚠️ 未找到有效的模型文件');
    }

    debugPrint('========== 文件验证完成 ==========');
  }

  /// 尝试多种编码方式解码字节数据
  String _decodeBytes(List<int> bytes) {
    if (bytes.isEmpty) return '';

    // 先尝试UTF-8
    try {
      final result = utf8.decode(bytes);
      // 检查是否有乱码字符
      if (!result.contains('�')) {
        return result;
      }
    } catch (e) {
      debugPrint('UTF-8解码失败: $e');
    }

    // 在Windows上尝试GBK编码（中文Windows系统默认编码）
    if (Platform.isWindows) {
      try {
        // 使用latin1先转换为字符串，然后重新编码
        final latin1String = latin1.decode(bytes);
        // 尝试将latin1解码的字符串重新编码为正确的中文
        return latin1String;
      } catch (e) {
        debugPrint('Latin1解码失败: $e');
      }
    }

    // 最后尝试系统默认编码
    try {
      return systemEncoding.decode(bytes);
    } catch (e) {
      debugPrint('系统编码解码失败: $e');
    }

    // 如果都失败了，返回原始字符串
    return String.fromCharCodes(bytes);
  }

  /// 查找可用的模型文件
  String? _findModelFile(String modelDir, List<String> candidates) {
    for (final candidate in candidates) {
      final filePath = path.join(modelDir, candidate);
      if (File(filePath).existsSync()) {
        return filePath;
      }
    }
    return null;
  }

  /// 获取可执行文件的完整路径
  String _getExecutablePath(String exeName) {
    final exePath = path.join(_dllDir, exeName);
    if (File(exePath).existsSync()) {
      return exePath;
    }
    throw Exception('未找到可执行文件: $exeName');
  }

  /// 获取可用的模型目录
  String _getAvailableModelDir() {
    final modelDirNames = [
      'speech_paraformer-large_asr_nat-zh-cn-16k-common-vocab8404-onnx',
      'paraformer-zh-streaming-onnx',
    ];

    for (final dirName in modelDirNames) {
      final fullPath = path.join(_modelDir, dirName);
      if (Directory(fullPath).existsSync()) {
        // 检查是否有模型文件
        final modelFile = _findModelFile(fullPath, [
          'model_quant.onnx',
          'model.onnx',
        ]);
        if (modelFile != null) {
          return fullPath;
        }
      }
    }
    throw Exception('未找到可用的模型目录');
  }

  /// 离线语音识别
  static Future<String> performOfflineRecognition(String wavFilePath) async {
    final instance = AsrFFI();
    if (!instance._initialized) {
      await instance._initialize();
    }

    return await instance._recognizeOffline(wavFilePath);
  }

  /// 在线语音识别（文件流式模拟）
  static Future<String> performOnlineRecognition(String wavFilePath) async {
    final instance = AsrFFI();
    if (!instance._initialized) {
      await instance._initialize();
    }

    return await instance._recognizeOnline(wavFilePath);
  }

  /// 内部离线识别实现
  Future<String> _recognizeOffline(String wavFilePath) async {
    try {
      final exePath = _getExecutablePath('funasr-onnx-offline.exe');
      final modelDir = _getAvailableModelDir();

      // 检查模型文件
      final modelFile = _findModelFile(modelDir, [
        'model_quant.onnx',
        'model.onnx',
      ]);
      if (modelFile == null) {
        throw Exception('未找到模型文件');
      }

      final useQuant = modelFile.contains('quant');

      return await _executeRecognitionProcess(
        exePath,
        modelDir,
        wavFilePath,
        useQuant,
      );
    } catch (e) {
      rethrow;
    }
  }

  /// 内部在线识别实现
  Future<String> _recognizeOnline(String wavFilePath) async {
    try {
      final exePath = _getExecutablePath('funasr-onnx-online-asr.exe');
      final modelDir = _getAvailableModelDir();

      final modelFile = _findModelFile(modelDir, [
        'model_quant.onnx',
        'model.onnx',
      ]);
      if (modelFile == null) {
        throw Exception('未找到模型文件');
      }

      final useQuant = modelFile.contains('quant');

      return await _executeRecognitionProcess(
        exePath,
        modelDir,
        wavFilePath,
        useQuant,
      );
    } catch (e) {
      rethrow;
    }
  }

  /// 执行识别进程
  Future<String> _executeRecognitionProcess(
    String exePath,
    String modelDir,
    String wavFilePath,
    bool useQuant,
  ) async {
    // 验证文件是否存在
    _writeInfoLog('开始执行识别进程...');
    _writeInfoLog('可执行文件: $exePath');
    _writeInfoLog('模型目录: $modelDir');
    _writeInfoLog('音频文件: $wavFilePath');
    _writeInfoLog('使用量化模型: $useQuant');

    debugPrint('开始执行识别进程...');
    debugPrint('可执行文件: $exePath');
    debugPrint('模型目录: $modelDir');
    debugPrint('音频文件: $wavFilePath');

    if (!File(exePath).existsSync()) {
      _writeErrorLog('可执行文件不存在: $exePath');
      throw Exception('可执行文件不存在: $exePath');
    } else {
      _writeInfoLog('✓ 可执行文件验证通过');
      debugPrint('✓ 可执行文件验证通过');
    }

    if (!Directory(modelDir).existsSync()) {
      _writeErrorLog('模型目录不存在: $modelDir');
      throw Exception('模型目录不存在: $modelDir');
    } else {
      _writeInfoLog('✓ 模型目录验证通过');
      debugPrint('✓ 模型目录验证通过');
    }

    if (!File(wavFilePath).existsSync()) {
      _writeErrorLog('音频文件不存在: $wavFilePath');
      throw Exception('音频文件不存在: $wavFilePath');
    } else {
      _writeInfoLog('✓ 音频文件验证通过');
      debugPrint('✓ 音频文件验证通过');
    }

    final exeDir = path.dirname(exePath);

    // 设置环境变量
    final env = Map<String, String>.from(Platform.environment);
    final pathSeparator = Platform.isWindows ? ';' : ':';
    env['PATH'] =
        '$exeDir$pathSeparator$_dllDir$pathSeparator${env['PATH'] ?? ''}';

    // 构建命令参数
    final args = [
      '--model-dir',
      modelDir,
      '--quantize',
      useQuant ? 'true' : 'false',
      '--bladedisc',
      'false',
      '--wav-path',
      wavFilePath,
      '--audio-fs',
      '16000',
    ];

    // 在Windows上设置控制台为UTF-8编码
    if (Platform.isWindows) {
      env['PYTHONIOENCODING'] = 'utf-8';
      env['LANG'] = 'zh_CN.UTF-8';
      // 先设置控制台编码为UTF-8
      try {
        await Process.run('chcp', ['65001'], environment: env);
      } catch (e) {
        debugPrint('设置控制台编码失败: $e');
      }
    }

    // 输出CMD命令
    _writeInfoLog('========== 命令执行详情 ==========');
    _writeInfoLog('工作目录: $exeDir');
    _writeInfoLog('PATH环境变量已更新包含: $exeDir 和 $_dllDir');
    _writeInfoLog('完整命令: $exePath ${args.join(' ')}');
    _writeInfoLog('是否使用量化模型: $useQuant');
    _writeInfoLog('===================================');

    debugPrint('========== 命令执行详情 ==========');
    debugPrint('工作目录: $exeDir');
    debugPrint('PATH环境变量已更新包含: $exeDir 和 $_dllDir');
    debugPrint('完整命令: $exePath ${args.join(' ')}');
    debugPrint('是否使用量化模型: $useQuant');
    debugPrint('===================================');

    // 执行进程
    ProcessResult result;
    try {
      _writeInfoLog('正在启动进程...');
      debugPrint('正在启动进程...');

      // 先检查系统依赖
      final depCheck = await checkSystemDependencies();
      if (depCheck['vcredist'] != null &&
          depCheck['vcredist']['installed'] == false) {
        _writeWarningLog('检测到缺少 Visual C++ Redistributable');
        debugPrint('⚠️ 警告: 检测到缺少 Visual C++ Redistributable');
      }

      result = await Process.run(
        exePath,
        args,
        environment: env,
        workingDirectory: exeDir,
        stderrEncoding: null, // 获取原始字节
        stdoutEncoding: null, // 获取原始字节
      );

      _writeInfoLog('进程执行完成，退出码: ${result.exitCode}');
    } catch (e) {
      _writeErrorLog('进程启动失败', e);
      debugPrint('进程启动失败: $e');

      // 特殊处理常见的Windows错误
      final errorMessage = e.toString();

      // 检查是否是调试DLL问题
      if (errorMessage.contains('MSVCP140D') ||
          errorMessage.contains('VCRUNTIME140D') ||
          errorMessage.contains('UCRTBASED')) {
        // 检查调试依赖
        final debugCheck = await _checkDebugDependencies();
        String debugDllList = '';
        if (debugCheck['hasDebugDlls'] == true) {
          debugDllList =
              '\n🔍 检测到的调试DLL: ${debugCheck['foundDebugDlls'].join(', ')}';
        }

        throw Exception(
          '❌ 调试版本DLL依赖错误\n\n'
          '🔍 问题: 应用程序依赖调试版本的Visual C++ DLL$debugDllList\n\n'
          '💡 解决方案:\n'
          '1. 重新编译项目，确保使用Release模式\n'
          '2. 检查CMakeLists.txt中的CMAKE_BUILD_TYPE设置\n'
          '3. 清理构建缓存: flutter clean\n'
          '4. 确保链接的是发布版本的库文件\n\n'
          '⚠️ 调试版本的DLL只在安装了Visual Studio的机器上可用\n'
          '📋 技术详情: $errorMessage',
        );
      }

      if (errorMessage.contains('0xC0000135') ||
          errorMessage.contains('-1073741515') ||
          errorMessage.contains('STATUS_DLL_NOT_FOUND')) {
        // 检查系统依赖
        final sysCheck = await checkSystemDependencies();
        String additionalInfo = '';

        if (sysCheck['vcredist']?['installed'] != true) {
          additionalInfo += '\n🔍 检测结果: Visual C++ Redistributable 未安装';
        }

        if (sysCheck['missingDlls']?['hasCriticalMissing'] == true) {
          final missing = sysCheck['missingDlls']['missingCritical'] as List;
          additionalInfo += '\n🔍 缺失的关键DLL: ${missing.join(', ')}';
        }

        throw Exception(
          '❌ 可执行文件无法启动 (错误代码: 0xC0000135)\n\n'
          '🔍 问题诊断: 缺少必要的系统依赖库$additionalInfo\n\n'
          '💡 解决方案:\n'
          '1. 安装 Microsoft Visual C++ Redistributable 2015-2022 (x64)\n'
          '   下载地址: https://aka.ms/vs/17/release/vc_redist.x64.exe\n\n'
          '2. 重启应用程序\n\n'
          '3. 如果问题仍然存在，请检查Windows系统更新\n\n'
          '4. 点击"检查系统依赖"按钮获取详细诊断\n\n'
          '📋 技术详情: $errorMessage',
        );
      } else if (errorMessage.contains('0xC0000005') ||
          errorMessage.contains('-1073741819')) {
        throw Exception(
          '❌ 内存访问违规 (错误代码: 0xC0000005)\n\n'
          '🔍 可能原因:\n'
          '• 模型文件损坏或不完整\n'
          '• 内存不足\n'
          '• 硬件兼容性问题\n\n'
          '💡 解决方案:\n'
          '1. 重新启动应用程序\n'
          '2. 检查可用内存空间\n'
          '3. 尝试使用不同的模型\n\n'
          '📋 技术详情: $errorMessage',
        );
      }

      throw Exception(
        '进程启动失败: $errorMessage\n\n'
        '💡 建议:\n'
        '1. 检查系统依赖项\n'
        '2. 确保所有文件已正确提取\n'
        '3. 尝试以管理员权限运行',
      );
    }

    debugPrint('退出码: ${result.exitCode}');

    // 记录退出码到日志
    if (result.exitCode == 0) {
      _writeInfoLog('进程正常完成，退出码: ${result.exitCode}');
    } else {
      _writeErrorLog('进程异常退出，退出码: ${result.exitCode}');
    }

    // 特殊处理常见的Windows错误代码
    if (result.exitCode == -1073741515) {
      // 0xC0000135
      throw Exception(
        '❌ 系统依赖缺失 (错误代码: 0xC0000135)\n\n'
        '🔍 问题: 无法找到或加载必要的DLL文件\n\n'
        '💡 解决方案:\n'
        '1. 安装 Microsoft Visual C++ Redistributable 2015-2022 (x64)\n'
        '   下载: https://aka.ms/vs/17/release/vc_redist.x64.exe\n\n'
        '2. 重启计算机\n\n'
        '3. 确保Windows系统已更新到最新版本\n\n'
        '📱 点击"检查系统依赖"按钮获取详细诊断信息',
      );
    } else if (result.exitCode == -1073741819) {
      // 0xC0000005
      throw Exception(
        '❌ 访问违规错误 (错误代码: 0xC0000005)\n\n'
        '🔍 可能原因:\n'
        '• 模型文件损坏或不完整\n'
        '• 内存访问错误\n'
        '• 权限不足\n\n'
        '💡 解决方案:\n'
        '1. 重新启动应用程序\n'
        '2. 尝试以管理员权限运行\n'
        '3. 检查模型文件完整性\n'
        '4. 释放更多系统内存',
      );
    } else if (result.exitCode == -1073740791) {
      // 0xC0000409
      throw Exception(
        '❌ 堆栈缓冲区溢出 (错误代码: 0xC0000409)\n\n'
        '🔍 问题: 程序检测到潜在的安全威胁\n\n'
        '💡 解决方案:\n'
        '1. 更新到最新版本的应用程序\n'
        '2. 检查防病毒软件是否误报\n'
        '3. 确保模型文件来源可信',
      );
    } else if (result.exitCode != 0) {
      debugPrint('进程异常退出，退出码: ${result.exitCode}');

      // 提供通用的退出码信息
      String errorHint = '';
      if (result.exitCode < 0) {
        final hexCode = (result.exitCode & 0xFFFFFFFF)
            .toRadixString(16)
            .toUpperCase();
        errorHint =
            '\n\n🔧 退出码: ${result.exitCode} (0x$hexCode)\n'
            '这通常表示系统级错误，建议检查系统依赖和权限。';
      }

      throw Exception(
        '❌ 进程执行失败\n\n'
        '🔍 退出码: ${result.exitCode}\n\n'
        '💡 建议:\n'
        '1. 点击"检查系统依赖"按钮诊断问题\n'
        '2. 查看详细的错误输出\n'
        '3. 确保所有必要文件已正确部署$errorHint',
      );
    }

    // 处理输出编码问题
    String stdout = '';
    String stderr = '';

    try {
      // 获取原始字节数据
      final stdoutBytes = result.stdout as List<int>;
      final stderrBytes = result.stderr as List<int>;

      _writeInfoLog('标准输出字节长度: ${stdoutBytes.length}');
      _writeInfoLog('错误输出字节长度: ${stderrBytes.length}');

      // 尝试多种编码方式解码
      stdout = _decodeBytes(stdoutBytes);
      stderr = _decodeBytes(stderrBytes);
    } catch (e) {
      _writeErrorLog('输出解码失败', e);
      debugPrint('输出解码失败: $e');
      stdout = result.stdout.toString();
      stderr = result.stderr.toString();
    }

    _writeInfoLog('标准输出内容: $stdout');
    _writeInfoLog('错误输出内容: $stderr');
    debugPrint('标准输出: $stdout');
    debugPrint('错误输出: $stderr');

    // 解析输出结果 - 可能在stdout或stderr中
    String output = stdout;

    // 如果stdout为空或只有很少内容，检查stderr
    if (output.trim().isEmpty || output.trim().length < 50) {
      debugPrint('标准输出较少，检查错误输出是否包含结果');

      // 检查stderr是否包含识别结果（有些程序将日志输出到stderr）
      if (stderr.contains('wav_default_id') ||
          stderr.contains(RegExp(r'[\u4e00-\u9fa5]'))) {
        debugPrint('在错误输出中找到可能的识别结果');
        output = stderr;
      }
    }

    if (result.exitCode != 0 && output.trim().isEmpty) {
      final errorMsg = '识别进程失败，退出码: ${result.exitCode}, 错误: $stderr';
      _writeErrorLog(errorMsg);
      throw Exception(errorMsg);
    }

    final finalResult = _parseRecognitionResult(output);
    _writeInfoLog('识别结果: $finalResult');

    // 强制刷新日志到文件
    await flushLogs();

    return finalResult;
  }

  /// 解析识别结果
  String _parseRecognitionResult(String output) {
    _writeInfoLog('开始解析输出，总长度: ${output.length}');
    debugPrint('开始解析输出，总长度: ${output.length}');

    if (output.isEmpty) {
      _writeWarningLog('输出为空');
      debugPrint('输出为空');
      return '未识别到内容';
    }

    final lines = output.split('\n');
    debugPrint('输出行数: ${lines.length}');

    // 查找包含识别结果的行
    for (int i = 0; i < lines.length; i++) {
      final line = lines[i].trim();
      if (line.isNotEmpty) {
        debugPrint('第${i + 1}行: $line');
      }

      // funasr 输出格式: wav_default_id : 识别文本
      if (line.contains('wav_default_id') && line.contains(' : ')) {
        final colonIndex = line.indexOf(' : ');
        if (colonIndex > 0) {
          final result = line.substring(colonIndex + 3).trim();
          if (result.isNotEmpty && !result.startsWith('I2025')) {
            _writeInfoLog('找到识别结果: $result');
            debugPrint('找到识别结果: $result');
            _recognitionHistory.add(result);
            return result;
          }
        }
      }

      // 备用匹配模式：查找包含中文字符的行
      if (line.contains(RegExp(r'[\u4e00-\u9fa5]')) &&
          !line.startsWith('I2025') &&
          !line.contains('model') &&
          !line.contains('Model') &&
          !line.contains('SUCCESS') &&
          line.length > 10) {
        _writeInfoLog('找到可能的中文识别结果: $line');
        debugPrint('找到可能的中文识别结果: $line');
        _recognitionHistory.add(line);
        return line;
      }
    }

    // 如果没有找到标准格式，尝试从整个输出中提取
    final cleanOutput = output
        .replaceAll(
          RegExp(r'I\d{8} \d{2}:\d{2}:\d{2}\.\d+ \d+ [^\s]+\s*'),
          '',
        ) // 移除日志前缀
        .replaceAll(RegExp(r'Model.*?takes.*?s'), '') // 移除性能统计
        .replaceAll(RegExp(r'Audio length:.*'), '')
        .replaceAll(RegExp(r'RTF:.*'), '')
        .trim();

    debugPrint('清理后的输出: $cleanOutput');

    if (cleanOutput.isNotEmpty &&
        cleanOutput.contains(RegExp(r'[\u4e00-\u9fa5]'))) {
      _writeInfoLog('使用清理后的输出作为结果: $cleanOutput');
      debugPrint('使用清理后的输出作为结果');
      _recognitionHistory.add(cleanOutput);
      return cleanOutput;
    }

    // 最后的备用方案
    _writeWarningLog('未找到任何识别结果');
    debugPrint('未找到任何识别结果');
    return '未识别到内容';
  }

  /// 获取识别历史
  static List<String> getRecognitionHistory() {
    return AsrFFI()._recognitionHistory;
  }

  /// 清除识别历史
  static void clearRecognitionHistory() {
    AsrFFI()._recognitionHistory.clear();
  }

  /// 检查是否已初始化
  static bool get isInitialized => AsrFFI()._initialized;

  /// 获取运行时目录（用于部署时参考）
  static Future<String> getRuntimeDirectory() async {
    String appDir;

    if (Platform.isWindows) {
      appDir = path.dirname(Platform.resolvedExecutable);
    } else if (Platform.isLinux || Platform.isMacOS) {
      appDir = path.dirname(Platform.resolvedExecutable);
    } else {
      final temp = await getTemporaryDirectory();
      appDir = temp.path;
    }

    return path.join(appDir, 'funasr_runtime');
  }

  /// 获取工作目录信息（用于调试）
  static Map<String, String> getDebugInfo() {
    final instance = AsrFFI();
    return {
      'workRoot': instance._workRoot,
      'dllDir': instance._dllDir,
      'modelDir': instance._modelDir,
      'initialized': instance._initialized.toString(),
      'historyCount': instance._recognitionHistory.length.toString(),
    };
  }

  /// 诊断系统状态（详细调试信息）
  static Future<Map<String, dynamic>> performDiagnostics() async {
    final instance = AsrFFI();
    final result = <String, dynamic>{};

    if (!instance._initialized) {
      await instance._initialize();
    }

    // 检查目录状态
    result['directories'] = {
      'workRoot': {
        'path': instance._workRoot,
        'exists': Directory(instance._workRoot).existsSync(),
      },
      'dllDir': {
        'path': instance._dllDir,
        'exists': Directory(instance._dllDir).existsSync(),
      },
      'modelDir': {
        'path': instance._modelDir,
        'exists': Directory(instance._modelDir).existsSync(),
      },
    };

    // 检查关键文件
    final keyFiles = ['funasr-onnx-offline.exe', 'onnxruntime.dll'];
    result['keyFiles'] = {};
    for (final fileName in keyFiles) {
      final filePath = path.join(instance._dllDir, fileName);
      result['keyFiles'][fileName] = {
        'path': filePath,
        'exists': File(filePath).existsSync(),
        'size': File(filePath).existsSync() ? File(filePath).lengthSync() : 0,
      };
    }

    // 检查模型目录
    result['models'] = {};
    try {
      final modelDir = instance._getAvailableModelDir();
      result['models']['selectedDir'] = modelDir;
      result['models']['dirExists'] = Directory(modelDir).existsSync();

      if (Directory(modelDir).existsSync()) {
        final files = Directory(modelDir).listSync();
        result['models']['files'] = {};
        for (final file in files) {
          if (file is File) {
            result['models']['files'][path.basename(file.path)] = file
                .lengthSync();
          }
        }
      }
    } catch (e) {
      result['models']['error'] = e.toString();
    }

    return result;
  }

  /// 获取详细的部署诊断信息
  static Future<Map<String, dynamic>> getDeploymentDiagnostic() async {
    final instance = AsrFFI();
    await instance._initialize();

    final info = <String, dynamic>{};

    // 平台信息
    info['platform'] = {
      'os': Platform.operatingSystem,
      'version': Platform.operatingSystemVersion,
      'executable': Platform.resolvedExecutable,
      'executableDir': path.dirname(Platform.resolvedExecutable),
    };

    // 目录结构
    info['directories'] = {
      'workRoot': instance._workRoot,
      'dllDir': instance._dllDir,
      'modelDir': instance._modelDir,
      'workRootExists': Directory(instance._workRoot).existsSync(),
      'dllDirExists': Directory(instance._dllDir).existsSync(),
      'modelDirExists': Directory(instance._modelDir).existsSync(),
    };

    // 关键可执行文件
    final executables = [
      'funasr-onnx-offline.exe',
      'funasr-onnx-2pass-rtf.exe',
    ];

    info['executables'] = <String, dynamic>{};
    for (final exe in executables) {
      final exePath = path.join(instance._dllDir, exe);
      final file = File(exePath);
      info['executables'][exe] = {
        'path': exePath,
        'exists': file.existsSync(),
        'size': file.existsSync() ? file.lengthSync() : 0,
        'canExecute': file.existsSync() && await instance._canExecute(exePath),
      };
    }

    // 关键DLL文件
    final dlls = [
      'onnxruntime.dll',
      'avcodec-60.dll',
      'avformat-60.dll',
      'avutil-58.dll',
    ];

    info['dlls'] = <String, dynamic>{};
    for (final dll in dlls) {
      final dllPath = path.join(instance._dllDir, dll);
      final file = File(dllPath);
      info['dlls'][dll] = {
        'path': dllPath,
        'exists': file.existsSync(),
        'size': file.existsSync() ? file.lengthSync() : 0,
      };
    }

    // 模型目录检查
    info['models'] = <String, dynamic>{};
    if (Directory(instance._modelDir).existsSync()) {
      final modelSubDirs = Directory(instance._modelDir)
          .listSync()
          .whereType<Directory>()
          .map((entity) => path.basename(entity.path))
          .toList();

      info['models']['availableModels'] = modelSubDirs;

      for (final modelName in modelSubDirs) {
        final modelPath = path.join(instance._modelDir, modelName);
        final files = Directory(modelPath)
            .listSync()
            .whereType<File>()
            .map((entity) => path.basename(entity.path))
            .toList();

        info['models'][modelName] = {
          'path': modelPath,
          'files': files,
          'hasOnnxModel': files.any((f) => f.endsWith('.onnx')),
          'hasConfigYaml': files.any((f) => f == 'config.yaml'),
          'hasTokens': files.any((f) => f.contains('token')),
        };
      }
    }

    return info;
  }

  /// 检查系统依赖项
  static Future<Map<String, dynamic>> checkSystemDependencies() async {
    final dependencies = <String, dynamic>{};

    // 检查Visual C++ Redistributable (发布版本)
    dependencies['vcredist'] = await _checkVCRedist();

    // 检查是否意外包含了调试版本的DLL
    dependencies['debugDlls'] = await _checkDebugDependencies();

    // 检查.NET Runtime (包括.NET Core/.NET 5+)
    dependencies['dotnet'] = await _checkDotNet();

    // 检查Windows版本
    dependencies['windows'] = _checkWindowsVersion();

    // 检查系统缺失的DLL文件
    dependencies['missingDlls'] = await _checkMissingSystemDlls();

    return dependencies;
  }

  /// 检查Visual C++ Redistributable
  static Future<Map<String, dynamic>> _checkVCRedist() async {
    final vcInfo = <String, dynamic>{};

    try {
      // 检查注册表中的VC++运行时 (发布版本)
      final result = await Process.run('reg', [
        'query',
        'HKLM\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x64',
        '/v',
        'Version',
      ], runInShell: true);

      if (result.exitCode == 0) {
        vcInfo['installed'] = true;
        vcInfo['details'] = result.stdout.toString();
        vcInfo['type'] = 'Release';
      } else {
        vcInfo['installed'] = false;
        vcInfo['error'] = 'VC++ Redistributable x64 not found in registry';
      }

      // 同时检查更新版本的VC++ Redistributable
      final result2022 = await Process.run('reg', [
        'query',
        'HKLM\\SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\X64',
        '/v',
        'Version',
      ], runInShell: true);

      if (result2022.exitCode == 0) {
        vcInfo['installed2022'] = true;
        vcInfo['details2022'] = result2022.stdout.toString();
      }
    } catch (e) {
      vcInfo['installed'] = false;
      vcInfo['error'] = e.toString();
    }

    return vcInfo;
  }

  /// 检查是否包含了调试版本的DLL (这些不应该在发布版本中)
  static Future<Map<String, dynamic>> _checkDebugDependencies() async {
    final debugInfo = <String, dynamic>{};
    final instance = AsrFFI();

    if (!instance._initialized) {
      await instance._initialize();
    }

    // 检查常见的调试版本DLL
    final debugDlls = [
      'MSVCP140D.dll',
      'VCRUNTIME140D.dll',
      'UCRTBASED.dll',
      'CONCRT140D.dll',
      'MSVCP140D_1.dll',
      'MSVCP140D_2.dll',
    ];

    debugInfo['foundDebugDlls'] = <String>[];
    debugInfo['hasDebugDlls'] = false;

    for (final dll in debugDlls) {
      final dllPath = path.join(instance._dllDir, dll);
      if (File(dllPath).existsSync()) {
        debugInfo['foundDebugDlls'].add(dll);
        debugInfo['hasDebugDlls'] = true;
      }
    }

    if (debugInfo['hasDebugDlls']) {
      debugInfo['warning'] = '⚠️ 检测到调试版本的DLL文件，这些文件不应该在发布版本中包含';
      debugInfo['recommendation'] = '请使用Release模式重新编译项目，并确保只包含发布版本的DLL';
      debugInfo['impact'] = '调试版本的DLL会导致在没有Visual Studio的机器上无法运行';
    }

    return debugInfo;
  }

  /// 检查.NET Runtime (包括.NET Framework和.NET Core/.NET 5+)
  static Future<Map<String, dynamic>> _checkDotNet() async {
    final dotnetInfo = <String, dynamic>{};

    // 检查.NET Core/.NET 5+ runtime
    try {
      final result = await Process.run('dotnet', ['--list-runtimes']);
      if (result.exitCode == 0) {
        dotnetInfo['dotnetCore'] = {
          'installed': true,
          'runtimes': result.stdout.toString().trim(),
        };

        // 解析运行时版本
        final runtimes = result.stdout.toString().split('\n');
        final aspNetRuntimes = runtimes
            .where((r) => r.contains('Microsoft.AspNetCore.App'))
            .toList();
        final netCoreRuntimes = runtimes
            .where((r) => r.contains('Microsoft.NETCore.App'))
            .toList();

        dotnetInfo['dotnetCore']['hasAspNet'] = aspNetRuntimes.isNotEmpty;
        dotnetInfo['dotnetCore']['hasNetCore'] = netCoreRuntimes.isNotEmpty;
      } else {
        dotnetInfo['dotnetCore'] = {
          'installed': false,
          'error': 'dotnet command not found or failed',
        };
      }
    } catch (e) {
      dotnetInfo['dotnetCore'] = {'installed': false, 'error': e.toString()};
    }

    // 检查.NET Framework (通过注册表)
    try {
      final frameworkResult = await Process.run('reg', [
        'query',
        'HKLM\\SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full',
        '/v',
        'Release',
      ], runInShell: true);

      if (frameworkResult.exitCode == 0) {
        dotnetInfo['netFramework'] = {
          'installed': true,
          'details': frameworkResult.stdout.toString(),
        };

        // 解析.NET Framework版本
        final output = frameworkResult.stdout.toString();
        if (output.contains('Release')) {
          final match = RegExp(
            r'Release\s+REG_DWORD\s+0x([0-9a-fA-F]+)',
          ).firstMatch(output);
          if (match != null) {
            final releaseNumber = int.parse(match.group(1)!, radix: 16);
            dotnetInfo['netFramework']['version'] = _getNetFrameworkVersion(
              releaseNumber,
            );
          }
        }
      } else {
        dotnetInfo['netFramework'] = {
          'installed': false,
          'error': '.NET Framework not found in registry',
        };
      }
    } catch (e) {
      dotnetInfo['netFramework'] = {'installed': false, 'error': e.toString()};
    }

    // 检查是否有任何.NET runtime可用
    dotnetInfo['hasAnyDotNet'] =
        (dotnetInfo['dotnetCore']?['installed'] == true) ||
        (dotnetInfo['netFramework']?['installed'] == true);

    if (!dotnetInfo['hasAnyDotNet']) {
      dotnetInfo['recommendation'] = {
        'message': '未检测到任何.NET运行时',
        'solutions': [
          '安装.NET 6.0 Runtime: https://dotnet.microsoft.com/download/dotnet/6.0',
          '安装.NET Framework 4.8: https://dotnet.microsoft.com/download/dotnet-framework/net48',
          '检查应用程序是否真的需要.NET (某些原生应用可能不需要)',
        ],
      };
    }

    return dotnetInfo;
  }

  /// 根据Release编号获取.NET Framework版本
  static String _getNetFrameworkVersion(int releaseNumber) {
    if (releaseNumber >= 533320) return '4.8.1';
    if (releaseNumber >= 528040) return '4.8';
    if (releaseNumber >= 461808) return '4.7.2';
    if (releaseNumber >= 461308) return '4.7.1';
    if (releaseNumber >= 460798) return '4.7';
    if (releaseNumber >= 394802) return '4.6.2';
    if (releaseNumber >= 394254) return '4.6.1';
    if (releaseNumber >= 393295) return '4.6';
    if (releaseNumber >= 379893) return '4.5.2';
    if (releaseNumber >= 378675) return '4.5.1';
    if (releaseNumber >= 378389) return '4.5';
    return 'Unknown';
  }

  /// 检查Windows版本
  static Map<String, dynamic> _checkWindowsVersion() {
    return {
      'os': Platform.operatingSystem,
      'version': Platform.operatingSystemVersion,
      'isWindows': Platform.isWindows,
    };
  }

  /// 检查缺失的系统DLL文件
  static Future<Map<String, dynamic>> _checkMissingSystemDlls() async {
    final dllInfo = <String, dynamic>{};
    final instance = AsrFFI();

    if (!instance._initialized) {
      await instance._initialize();
    }

    // 检查关键的系统DLL文件
    final systemDlls = [
      'kernel32.dll',
      'msvcrt.dll',
      'user32.dll',
      'ole32.dll',
      'oleaut32.dll',
      'advapi32.dll',
      'shell32.dll',
      'comctl32.dll',
      'gdi32.dll',
      'winmm.dll',
      'wsock32.dll',
      'ws2_32.dll',
    ];

    // 检查VC++ Redistributable相关的DLL
    final vcRedistDlls = [
      'msvcp140.dll', // Visual C++ 2015-2022 Redistributable
      'vcruntime140.dll', // Visual C++ 2015-2022 Redistributable
      'vcruntime140_1.dll',
      'msvcp140_1.dll',
      'msvcp140_2.dll',
      'concrt140.dll',
      'api-ms-win-crt-runtime-l1-1-0.dll', // Universal C Runtime
    ];

    dllInfo['systemDlls'] = <String, dynamic>{};
    dllInfo['vcRedistDlls'] = <String, dynamic>{};
    dllInfo['missingCritical'] = <String>[];

    // 检查系统DLL (这些通常都应该存在)
    for (final dll in systemDlls) {
      final exists = await _checkDllExists(dll);
      dllInfo['systemDlls'][dll] = exists;
      if (!exists) {
        dllInfo['missingCritical'].add(dll);
      }
    }

    // 检查VC++ Redistributable DLL
    for (final dll in vcRedistDlls) {
      final exists = await _checkDllExists(dll);
      dllInfo['vcRedistDlls'][dll] = exists;
      if (!exists && (dll == 'msvcp140.dll' || dll == 'vcruntime140.dll')) {
        dllInfo['missingCritical'].add(dll);
      }
    }

    // 生成建议
    if (dllInfo['missingCritical'].isNotEmpty) {
      dllInfo['hasCriticalMissing'] = true;
      dllInfo['recommendations'] = [];

      if (dllInfo['missingCritical'].contains('msvcp140.dll') ||
          dllInfo['missingCritical'].contains('vcruntime140.dll')) {
        dllInfo['recommendations'].add({
          'issue': 'Visual C++ Redistributable DLL缺失',
          'solution': '安装Microsoft Visual C++ Redistributable 2015-2022 (x64)',
          'download': 'https://aka.ms/vs/17/release/vc_redist.x64.exe',
        });
      }

      if (dllInfo['missingCritical'].any((dll) => systemDlls.contains(dll))) {
        dllInfo['recommendations'].add({
          'issue': '系统DLL文件缺失',
          'solution': '系统文件可能损坏，建议运行系统文件检查器',
          'command': 'sfc /scannow (以管理员身份运行)',
        });
      }
    } else {
      dllInfo['hasCriticalMissing'] = false;
    }

    return dllInfo;
  }

  /// 检查特定DLL是否存在于系统中
  static Future<bool> _checkDllExists(String dllName) async {
    try {
      // 使用where命令查找DLL
      final result = await Process.run('where', [dllName], runInShell: true);
      return result.exitCode == 0 && result.stdout.toString().trim().isNotEmpty;
    } catch (e) {
      // 如果where命令失败，尝试检查System32目录
      try {
        final systemPath = path.join(
          Platform.environment['SYSTEMROOT'] ?? 'C:\\Windows',
          'System32',
          dllName,
        );
        return File(systemPath).existsSync();
      } catch (e2) {
        return false;
      }
    }
  }

  /// 强制重新验证所有必需文件
  Future<void> forceReValidateFiles() async {
    debugPrint('强制重新验证所有必需文件...');
    await _setupWorkingDirectories();
    await _validateRequiredFiles();
    debugPrint('强制重新验证完成');
  }

  /// 静态方法：强制重新验证所有必需文件
  static Future<void> forceReExtractAssets() async {
    final instance = AsrFFI();
    await instance.forceReValidateFiles();
  }

  /// 检查文件是否可执行
  Future<bool> _canExecute(String filePath) async {
    try {
      if (Platform.isWindows) {
        // Windows上检查文件扩展名
        return filePath.toLowerCase().endsWith('.exe');
      } else {
        // Unix系统检查执行权限
        final result = await Process.run('test', ['-x', filePath]);
        return result.exitCode == 0;
      }
    } catch (e) {
      return false;
    }
  }

  /// 检查音频文件格式是否支持
  static bool isAudioFileSupported(String filePath) {
    final extension = path.extension(filePath).toLowerCase();
    final supportedFormats = ['.wav', '.mp3', '.flac', '.m4a', '.aac', '.ogg'];
    return supportedFormats.contains(extension);
  }

  /// 获取音频文件信息
  static Map<String, dynamic> getAudioFileInfo(String filePath) {
    final file = File(filePath);
    if (!file.existsSync()) {
      return {'exists': false, 'error': '文件不存在'};
    }

    final extension = path.extension(filePath).toLowerCase();
    final isSupported = isAudioFileSupported(filePath);
    final fileSize = file.lengthSync();

    return {
      'exists': true,
      'name': path.basename(filePath),
      'path': filePath,
      'extension': extension,
      'isSupported': isSupported,
      'size': fileSize,
      'sizeString': _formatFileSize(fileSize),
    };
  }

  /// 格式化文件大小
  static String _formatFileSize(int bytes) {
    if (bytes < 1024) return '$bytes B';
    if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
    if (bytes < 1024 * 1024 * 1024) {
      return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
    }
    return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
  }

  // ==================== 日志功能 ====================

  /// 初始化日志系统
  Future<void> _initializeLogging() async {
    if (_logFilePath != null) return;

    try {
      // 获取桌面路径
      final desktopPath = await _getDesktopPath();

      // 创建日志文件名（包含时间戳）
      final timestamp = DateFormat('yyyyMMdd_HHmmss').format(DateTime.now());
      final logFileName = 'asr_onnx_ffi_log_$timestamp.txt';
      _logFilePath = path.join(desktopPath, logFileName);

      // 创建日志文件并写入初始信息
      final logFile = File(_logFilePath!);
      await logFile.writeAsString(
        '========== ASR ONNX FFI 日志文件 ==========\n'
        '创建时间: ${DateFormat('yyyy-MM-dd HH:mm:ss').format(DateTime.now())}\n'
        '平台: ${Platform.operatingSystem} ${Platform.operatingSystemVersion}\n'
        '应用程序路径: ${Platform.resolvedExecutable}\n'
        '=========================================\n\n',
      );

      _writeLog('日志系统已初始化，日志文件: $_logFilePath');
    } catch (e) {
      debugPrint('初始化日志系统失败: $e');
      _enableLogging = false;
    }
  }

  /// 获取Windows桌面路径
  Future<String> _getDesktopPath() async {
    if (Platform.isWindows) {
      // 尝试从环境变量获取用户配置文件路径
      final userProfile = Platform.environment['USERPROFILE'];
      if (userProfile != null) {
        final desktopPath = path.join(userProfile, 'Desktop');
        if (Directory(desktopPath).existsSync()) {
          return desktopPath;
        }
      }

      // 备用方案：尝试从HOMEDRIVE和HOMEPATH组合
      final homeDrive = Platform.environment['HOMEDRIVE'];
      final homePath = Platform.environment['HOMEPATH'];
      if (homeDrive != null && homePath != null) {
        final desktopPath = path.join(homeDrive + homePath, 'Desktop');
        if (Directory(desktopPath).existsSync()) {
          return desktopPath;
        }
      }

      // 最后的备用方案：使用临时目录
      final tempDir = await getTemporaryDirectory();
      return tempDir.path;
    } else {
      // 非Windows平台，使用临时目录
      final tempDir = await getTemporaryDirectory();
      return tempDir.path;
    }
  }

  /// 写入日志
  static void _writeLog(String message, {String level = 'INFO'}) {
    if (!_enableLogging) return;

    final timestamp = DateFormat(
      'yyyy-MM-dd HH:mm:ss.SSS',
    ).format(DateTime.now());
    final logEntry = '[$timestamp] [$level] $message';

    // 添加到内存缓冲区
    _logBuffer.add(logEntry);

    // 同时输出到控制台
    debugPrint(logEntry);

    // 异步写入文件
    _flushLogToFile();
  }

  /// 将日志缓冲区写入文件
  static void _flushLogToFile() async {
    if (_logFilePath == null || _logBuffer.isEmpty) return;

    try {
      final logFile = File(_logFilePath!);
      final logsToWrite = List<String>.from(_logBuffer);
      _logBuffer.clear();

      // 追加写入日志文件
      await logFile.writeAsString(
        '${logsToWrite.join('\n')}\n',
        mode: FileMode.append,
      );
    } catch (e) {
      debugPrint('写入日志文件失败: $e');
    }
  }

  /// 记录错误日志
  static void _writeErrorLog(
    String message, [
    dynamic error,
    StackTrace? stackTrace,
  ]) {
    String fullMessage = message;
    if (error != null) {
      fullMessage += '\n错误详情: $error';
    }
    if (stackTrace != null) {
      fullMessage += '\n堆栈跟踪:\n$stackTrace';
    }
    _writeLog(fullMessage, level: 'ERROR');
  }

  /// 记录警告日志
  static void _writeWarningLog(String message) {
    _writeLog(message, level: 'WARNING');
  }

  /// 记录信息日志
  static void _writeInfoLog(String message) {
    _writeLog(message, level: 'INFO');
  }

  /// 获取当前日志文件路径
  static String? getLogFilePath() => _logFilePath;

  /// 开启/关闭日志记录
  static void setLoggingEnabled(bool enabled) {
    _enableLogging = enabled;
    _writeInfoLog('日志记录已${enabled ? '开启' : '关闭'}');
  }

  /// 清空日志缓冲区并强制写入文件
  static Future<void> flushLogs() async {
    if (_logFilePath != null && _logBuffer.isNotEmpty) {
      _flushLogToFile();
      // 等待一小段时间确保写入完成
      await Future.delayed(const Duration(milliseconds: 100));
    }
  }

  /// 获取日志文件内容
  static Future<String> getLogFileContent() async {
    if (_logFilePath == null || !File(_logFilePath!).existsSync()) {
      return '日志文件不存在';
    }

    try {
      return await File(_logFilePath!).readAsString();
    } catch (e) {
      return '读取日志文件失败: $e';
    }
  }

  /// 删除日志文件
  static Future<bool> deleteLogFile() async {
    if (_logFilePath == null) return false;

    try {
      final logFile = File(_logFilePath!);
      if (logFile.existsSync()) {
        await logFile.delete();
        _writeInfoLog('日志文件已删除: $_logFilePath');
        return true;
      }
      return false;
    } catch (e) {
      _writeErrorLog('删除日志文件失败', e);
      return false;
    }
  }

  /// 打开日志文件所在文件夹
  static Future<void> openLogFileFolder() async {
    if (_logFilePath == null) return;

    try {
      final logDir = path.dirname(_logFilePath!);
      if (Platform.isWindows) {
        await Process.run('explorer', [logDir]);
      } else if (Platform.isMacOS) {
        await Process.run('open', [logDir]);
      } else if (Platform.isLinux) {
        await Process.run('xdg-open', [logDir]);
      }
      _writeInfoLog('已打开日志文件夹: $logDir');
    } catch (e) {
      _writeErrorLog('打开日志文件夹失败', e);
    }
  }
}
